#include "ghostboarditems.h"
#include "tileboarditems.h"
#include "gameboardorganizer.h"
#include <QPainter>
#include "gameanimation.h"
#include <QStyleOption>
#include "player.h"
#include "windowskin.h"
#include "ghost.h"
#include "gametable.h"
#include "infoboard.h"
#include <QBitmap>
#include <QDebug>
#include "gamedialogmanager.h"
/*


  GHOST SLOT GHOST ITEM CLASS


  */

GhostSlotGhostItem::GhostSlotGhostItem(GameBoardOrganizer* parent, GameBoardItem* parentItem)
    :GameBoardItem(parent, parentItem)
{
    showAnim = new GameParAnimation(this);
    showAnim->addFade(this, 0, 1, 300);
    hideAnim = new GameParAnimation(this);
    hideAnim->addFade(this, 1, 0, 300);
}

QRectF GhostSlotGhostItem::boundingRect() const{
    return QRectF(-SLOT_WIDTH/2, -SLOT_HEIGHT/2, SLOT_WIDTH, SLOT_HEIGHT);
}

void GhostSlotGhostItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    if(!_ghost.isNull())
        painter->drawPixmap(boundingRect(), _ghost, QRectF(0,0,SLOT_WIDTH, SLOT_HEIGHT));
}

void GhostSlotGhostItem::setGhost(Ghost *g){
    _ghostData = g;
    if(g==0){
        hideAnim->startUntilStop();
        setVisible(false);
    }
    else{
        setOpacity(0);
        setVisible(true);
        _ghost = QPixmap(g->getImagePath()).scaled(QSize(SLOT_WIDTH*2, SLOT_HEIGHT*2), Qt::KeepAspectRatio).copy(SLOT_WIDTH/2, SLOT_HEIGHT/2, SLOT_WIDTH, SLOT_HEIGHT);
        showAnim->startUntilStop();
    }
}


/*


  GHOST SLOT CLASS


  */

GhostSlot::GhostSlot(GameBoardOrganizer *board)
    :GameBoardItem(board)
{
    setAcceptHoverEvents(true);
    _frame = WindowSkin::createWindowFrame(SLOT_WIDTH, SLOT_HEIGHT, TouhouStyle2);
    _bg = QPixmap(":/common/images/slot_bg.png");

    _ghost = new GhostSlotGhostItem(this->getParentBoard(),this);
    //initally empty
    _ghost->setGhost(0);
}

QRectF GhostSlot::boundingRect() const{
    return QRectF(-SLOT_WIDTH/2, -SLOT_HEIGHT/2, SLOT_WIDTH, SLOT_HEIGHT);
}

void GhostSlot::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    //bool down = option->state & QStyle::State_Sunken;
    //bool over = option->state & QStyle::State_MouseOver;
    //QRectF f = boundingRect();
    //f.setWidth(SLOT_WIDTH-4);
    //f.setHeight(SLOT_HEIGHT-4);
    //f.translate(2, 2);
    QPen pen(QBrush(Qt::white), 2);
    painter->setPen(pen);
    painter->drawRect(boundingRect());
    painter->drawPixmap(-_bg.width()/2, -_bg.height()/2, _bg);
}

Ghost* GhostSlot::getGhostData(){
    return _ghost->getGhost();
}

void GhostSlot::createAnim(){
    //b_anim = new GameSeqAnimation(this);
    //b_anim->addFade(bottom, 0, 1, 400);
    //b_anim->addFade(bottom, 1, 0, 400);
    //b_anim->setLoopCount(-1);
}

void GhostSlot::setGhostCard(Ghost *g){
    _ghost->setGhost(g);
}

void GhostSlot::removeGhostCard(){
    Ghost * ghost = getGhostData();
    _ghost->setGhost(NULL);
    ghost->exocise();
}



void GhostSlot::haunt(){
    TileBoard* tiles = getTileBoard();
    switch(getBoardIndex()){
    case 0:
        //bottom board
        if(!tiles->getVillageAt(getSlotIndex(), 2)->haunted()){
            //if the corresponding tile is not yet haunted, haunt it.
            tiles->getVillageAt(getSlotIndex(), 2)->setHaunted(true);
        }else{
            //else check all tiles to find a tile that is not yet haunted.
            switch(getSlotIndex()){
            case 0:
            case 1:
                for(int i=1; i<3; i++){
                    if(!tiles->getVillageAt(i, 2)->haunted()){
                        //if the corresponding tile is not yet haunted, haunt it.
                        tiles->getVillageAt(i, 2)->setHaunted(true);
                        break;
                    }
                }
                break;
            case 2:
                for(int i=1; i>=0; i--){
                    if(!tiles->getVillageAt(i, 2)->haunted()){
                        //if the corresponding tile is not yet haunted, haunt it.
                        tiles->getVillageAt(i, 2)->setHaunted(true);
                        break;
                    }
                }
                break;
            }
        }
        break;
    case 1:
        //right board
        if(!tiles->getVillageAt(2, 2-getSlotIndex())->haunted()){
            //if the corresponding tile is not yet haunted, haunt it.
            tiles->getVillageAt(2, 2-getSlotIndex())->setHaunted(true);
        }else{
            //else check all tiles to find a tile that is not yet haunted.
            switch(getSlotIndex()){
            case 0:
            case 1:
                for(int i=1; i<3; i++){
                    if(!tiles->getVillageAt(2, 2-i)->haunted()){
                        //if the corresponding tile is not yet haunted, haunt it.
                        tiles->getVillageAt(2, 2-i)->setHaunted(true);
                        break;
                    }
                }
                break;
            case 2:
                for(int i=1; i>=0; i--){
                    if(!tiles->getVillageAt(2, 2-i)->haunted()){
                        //if the corresponding tile is not yet haunted, haunt it.
                        tiles->getVillageAt(2, 2-i)->setHaunted(true);
                        break;
                    }
                }
                break;
            }
        }
        break;
    case 2:
        //top board
        if(!tiles->getVillageAt(2-getSlotIndex(), 0)->haunted()){
            //if the corresponding tile is not yet haunted, haunt it.
            tiles->getVillageAt(2-getSlotIndex(), 0)->setHaunted(true);
        }else{
            //else check all tiles to find a tile that is not yet haunted.
            switch(getSlotIndex()){
            case 0:
            case 1:
                for(int i=1; i<3; i++){
                    if(!tiles->getVillageAt(2-i, 0)->haunted()){
                        //if the corresponding tile is not yet haunted, haunt it.
                        tiles->getVillageAt(2-i, 0)->setHaunted(true);
                        break;
                    }
                }
                break;
            case 2:
                for(int i=1; i>=0; i--){
                    if(!tiles->getVillageAt(2-i, 0)->haunted()){
                        //if the corresponding tile is not yet haunted, haunt it.
                        tiles->getVillageAt(2-i, 0)->setHaunted(true);
                        break;
                    }
                }
                break;
            }
        }
        break;
    case 3:
        //left board
        if(!tiles->getVillageAt(0, getSlotIndex())->haunted()){
            //if the corresponding tile is not yet haunted, haunt it.
            tiles->getVillageAt(0, getSlotIndex())->setHaunted(true);
        }else{
            //else check all tiles to find a tile that is not yet haunted.
            switch(getSlotIndex()){
            case 0:
            case 1:
                for(int i=1; i<3; i++){
                    if(!tiles->getVillageAt(0, i)->haunted()){
                        //if the corresponding tile is not yet haunted, haunt it.
                        tiles->getVillageAt(0, i)->setHaunted(true);
                        break;
                    }
                }
                break;
            case 2:
                for(int i=1; i>=0; i--){
                    if(!tiles->getVillageAt(0, i)->haunted()){
                        //if the corresponding tile is not yet haunted, haunt it.
                        tiles->getVillageAt(0, i)->setHaunted(true);
                        break;
                    }
                }
                break;
            }
        }
        break;
    default:
        break;
    }
}



int GhostSlot::getSlotIndex(){
    return ((GhostBoard*)getParentBoard())->getSlots().indexOf(this);
}

int GhostSlot::getBoardIndex(){
    return ((GhostBoard*)getParentBoard())->getBoardIndex();
}

TileBoard* GhostSlot::getTileBoard(){
    return ((CenterTable*)(getParentBoard()->getParentBoard()))->getTileBoard();
}

void GhostSlot::mousePressEvent(QGraphicsSceneMouseEvent *event){
    emit clicked(this);
    haunt();
    update();
}

void GhostSlot::hoverEnterEvent(QGraphicsSceneHoverEvent *event){
    //b_anim->start();
    //this->setScale(1.1);
    update();
}

void GhostSlot::hoverLeaveEvent(QGraphicsSceneHoverEvent *event){
    //b_anim->stop();
    //bottom->setOpacity(0);
    //this->setScale(1);
    update();
}

PlayerHeadArea::PlayerHeadArea(GameBoardOrganizer *b)
    :GameBoardItem(b)
{
    _frame = WindowSkin::createWindowFrame(boundingRect().width(), boundingRect().height(), TouhouStyle2);
}

QRectF PlayerHeadArea::boundingRect() const{
    return QRectF(-WIDTH/2, -HEIGHT/2, WIDTH, HEIGHT);
}

void PlayerHeadArea::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    if(!_head.isNull())
        painter->drawPixmap(-_head.width()/2, -_head.height()/2, _head);
    Player* player = ((GhostBoard*)this->getParentBoard())->getPlayer();
    //painter->drawPixmap(-_frame.width()/2, -_frame.height()/2, _frame);
    if(player!=0){
        int startX = WIDTH/2-_qi.width()-(player->getQi()-1)*10;
        for(int i = 0; i<player->getQi(); i++)
            painter->drawPixmap(startX+i*10, 25, _qi);
    }
}

void PlayerHeadArea::createHeadForBoard(GSColor _c, int _id){
    QPixmap p;
    switch(_c){
    case YELLOW:
        p = QPixmap(":/playerHead/images/y_taoist.png");
        break;
    case RED:
        p = QPixmap(":/playerHead/images/r_taoist.png");
        break;
    case GREEN:
        p = QPixmap(":/playerHead/images/g_taoist.png");
        break;
    case BLUE:
        p = QPixmap(":/playerHead/images/b_taoist.png");
        break;
    default:
        break;
    }
    QTransform t1, t2, t3;
    switch(_id){
    case 0:
        p = p.copy(QRect(2, 12, 116, 96));
        break;
    case 1:
        p = p.copy(QRect(12, 2, 96, 116));
        t1.rotate(90);
        p = p.transformed(t1);
        break;
    case 2:
        p = p.copy(QRect(2, 12, 116, 96));
        t2.rotate(180);
        p = p.transformed(t2);
        break;
    case 3:
        p = p.copy(QRect(12, 2, 96, 116));
        t3.rotate(-90);
        p = p.transformed(t3);
        break;
    default:
        break;
    }

    _head = p;

    p = QPixmap(":/playerHead/images/qi_icon.png");
    switch(_id){
    case 0:
        break;
    case 1:
        p = p.transformed(t1);
        break;
    case 2:
        p = p.transformed(t2);
        break;
    case 3:
        p = p.transformed(t3);
        break;
    default:
        break;
    }

    _qi = p;
}


/*

  GHOST BOARD BOTTOM CLASS

*/
GhostBoardBottom::GhostBoardBottom(GameBoardOrganizer *b)
    :GameBoardItem(b){
    moveBy((WIDTH - GhostSlot::WIDTH*3)/2, 0);
}

QRectF GhostBoardBottom::boundingRect() const{
    return QRectF(-WIDTH/2, -HEIGHT/2, WIDTH, HEIGHT);
}

void GhostBoardBottom::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

    if(!_bg.isNull())
        painter->drawPixmap(-_bg.width()/2, -_bg.height()/2, _bg);

}

void GhostBoardBottom::createBoardBottom(GSColor c){
    QPixmap pix(WIDTH, HEIGHT);
    QPainter p;
    QPainterPath path;
    QPen pen(Qt::white, 2);

    path.addRoundRect(0, 0, WIDTH, HEIGHT, 15);
    path.addRect(0, 0, 30, HEIGHT);
    path.addRect(0, 0, WIDTH, 30);
    path.setFillRule(Qt::WindingFill);
    pix.fill(Qt::transparent);
    p.begin(&pix);
    p.setPen(pen);
    switch(c){
    case YELLOW:
        p.fillPath(path, QColor(235, 211, 78, 255));
        break;
    case BLUE:
        p.fillPath(path, QColor(78, 130, 235, 255));
        break;
    case RED:
        p.fillPath(path, QColor(208, 54, 54, 255));
        break;
    case GREEN:
        p.fillPath(path, QColor(110, 216, 92, 255));

        break;
    default:
        break;
    }
    p.end();
    _bg = pix;
}

/*

  GHOST BOARD Top CLASS

*/
GhostBoardTop::GhostBoardTop(GameBoardOrganizer *b)
    :GameBoardItem(b){
    _frame = WindowSkin::createWindowFrame(WIDTH, HEIGHT, FFStyle);
    moveBy((WIDTH - GhostSlot::WIDTH*3)/2, 0);
}

QRectF GhostBoardTop::boundingRect() const{
    return QRectF(-WIDTH/2, -HEIGHT/2, WIDTH, HEIGHT);
}

void GhostBoardTop::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

    //painter->drawPixmap(-_frame.width()/2, -_frame.height()/2, _frame);
}


